using System.Configuration;

namespace m.Channelvn.Cached.Base
{
    public abstract class HtmlControlCacheBase
    {
        protected CacheSettings.ControlSetting _controlSetting;

        public HtmlControlCacheBase(CacheSettings.ControlSetting controlSetting)
        {
            this._controlSetting = controlSetting;
        }

        protected abstract string CacheName { get; }
        protected abstract string CurrentCache { get; }
        protected abstract string ParentCategory { get; }

        public void UpdateCache(System.Web.UI.Page currentPage)
        {
            string containerId = this._controlSetting.ContainerID;
            // Control Container
            System.Web.UI.Control ctrlContainer = FindControlRecursive((null != currentPage.Master ? (System.Web.UI.Control)currentPage.Master : (System.Web.UI.Control)currentPage), containerId);

            // Has this container and this is a HtmlContainerControl
            if (null != ctrlContainer && ctrlContainer is System.Web.UI.HtmlControls.HtmlContainerControl)
            {
                string cacheData = "";

                if (_controlSetting.EnableCache)
                {
                    cacheData = CurrentCache;
                }
                // if cache exists -> update cache to output
                if (!string.IsNullOrEmpty(cacheData) && CacheController.IsAllowDistributedCached)
                {
                    ((System.Web.UI.HtmlControls.HtmlContainerControl)ctrlContainer).InnerHtml = cacheData;
                }
                else // cache not exists -> Load control and update cache
                {
                    ControlBase ctrlControl = (ControlBase)currentPage.LoadControl(_controlSetting.FilePath);
                    if (null != ctrlControl)
                    {
                        ctrlControl.ControlCacheName = CacheName; // Cache name
                        ctrlControl.ControlCacheSetting = _controlSetting; // Cache name
                        ctrlControl.EnableViewState = _controlSetting.EnableViewState;
                        ctrlControl.ParentCategory = ParentCategory;

                        if (null != _controlSetting.Properties)
                        {
                            string[] keys = new string[_controlSetting.Properties.Keys.Count];
                            _controlSetting.Properties.Keys.CopyTo(keys, 0);
                            int propertyCount = keys.Length;
                            for (int i = 0; i < propertyCount; i++)
                            {
                                ctrlControl.SetProperty(keys[i], _controlSetting.Properties[keys[i]]);
                            }
                        }

                        if (!ctrlContainer.Controls.Contains(ctrlControl)) //ctrlContainer.Controls.Remove(ctrlControl);
                            ctrlContainer.Controls.Add(ctrlControl);
                    }
                }
            }
        }

        // Find control in master page and inner page
        private System.Web.UI.Control FindControlRecursive(System.Web.UI.Control root, string id)
        {
            if (root.ID == id) return root;

            for (int i = 0; i < root.Controls.Count; i++)
            {
                System.Web.UI.Control foundCtl = FindControlRecursive(root.Controls[i], id);

                if (foundCtl != null) return foundCtl;
            }
            return null;
        }
    }
}
